{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "name": "fer2013.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "machine_shape": "hm",
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Environment (conda_tensorflow_p36)",
      "language": "python",
      "name": "conda_tensorflow_p36"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.5"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/amilkh/cs230-fer/blob/transfer-learning/Final-SeNet50_WCW.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "gwdg7Sv3XBaP",
        "outputId": "e6d57857-34c2-43cb-fb06-55218d2a916e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 527
        }
      },
      "source": [
        "%tensorflow_version 1.x\n",
        "!pip install keras-vggface\n",
        "!pip install scikit-image\n",
        "!pip install pydot"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Collecting keras-vggface\n",
            "  Downloading https://files.pythonhosted.org/packages/2f/7d/5f0319ebdc09ac1a2272364fa9583f5067b6f8aff93fbbf8835d81cbaad7/keras_vggface-0.6-py3-none-any.whl\n",
            "Requirement already satisfied: pyyaml in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (3.13)\n",
            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (1.12.0)\n",
            "Requirement already satisfied: scipy>=0.14 in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (1.4.1)\n",
            "Requirement already satisfied: keras in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (2.2.5)\n",
            "Requirement already satisfied: pillow in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (7.0.0)\n",
            "Requirement already satisfied: numpy>=1.9.1 in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (1.18.1)\n",
            "Requirement already satisfied: h5py in /usr/local/lib/python3.6/dist-packages (from keras-vggface) (2.8.0)\n",
            "Requirement already satisfied: keras-applications>=1.0.8 in /usr/local/lib/python3.6/dist-packages (from keras->keras-vggface) (1.0.8)\n",
            "Requirement already satisfied: keras-preprocessing>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from keras->keras-vggface) (1.1.0)\n",
            "Installing collected packages: keras-vggface\n",
            "Successfully installed keras-vggface-0.6\n",
            "Requirement already satisfied: scikit-image in /usr/local/lib/python3.6/dist-packages (0.16.2)\n",
            "Requirement already satisfied: matplotlib!=3.0.0,>=2.0.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (3.2.0)\n",
            "Requirement already satisfied: networkx>=2.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (2.4)\n",
            "Requirement already satisfied: imageio>=2.3.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (2.4.1)\n",
            "Requirement already satisfied: pillow>=4.3.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (7.0.0)\n",
            "Requirement already satisfied: PyWavelets>=0.4.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (1.1.1)\n",
            "Requirement already satisfied: scipy>=0.19.0 in /usr/local/lib/python3.6/dist-packages (from scikit-image) (1.4.1)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib!=3.0.0,>=2.0.0->scikit-image) (0.10.0)\n",
            "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib!=3.0.0,>=2.0.0->scikit-image) (2.4.6)\n",
            "Requirement already satisfied: numpy>=1.11 in /usr/local/lib/python3.6/dist-packages (from matplotlib!=3.0.0,>=2.0.0->scikit-image) (1.18.1)\n",
            "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib!=3.0.0,>=2.0.0->scikit-image) (2.8.1)\n",
            "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib!=3.0.0,>=2.0.0->scikit-image) (1.1.0)\n",
            "Requirement already satisfied: decorator>=4.3.0 in /usr/local/lib/python3.6/dist-packages (from networkx>=2.0->scikit-image) (4.4.2)\n",
            "Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from cycler>=0.10->matplotlib!=3.0.0,>=2.0.0->scikit-image) (1.12.0)\n",
            "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from kiwisolver>=1.0.1->matplotlib!=3.0.0,>=2.0.0->scikit-image) (45.2.0)\n",
            "Requirement already satisfied: pydot in /usr/local/lib/python3.6/dist-packages (1.3.0)\n",
            "Requirement already satisfied: pyparsing>=2.1.4 in /usr/local/lib/python3.6/dist-packages (from pydot) (2.4.6)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "2nz38mJZXN_P",
        "outputId": "e76938ac-db5e-4674-d5a2-36da22abd4f2",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "\n",
        "import tensorflow as tf\n",
        "from tensorflow.keras.layers import *\n",
        "from tensorflow.python.lib.io import file_io\n",
        "\n",
        "%matplotlib inline\n",
        "\n",
        "import keras\n",
        "from keras import backend as K\n",
        "from keras.callbacks import ModelCheckpoint, EarlyStopping\n",
        "from keras.models import load_model\n",
        "from keras.preprocessing.image import ImageDataGenerator\n",
        "from keras_vggface.vggface import VGGFace\n",
        "from keras.utils import plot_model\n",
        "from sklearn.metrics import *\n",
        "from keras.engine import Model\n",
        "from keras.layers import Input, Flatten, Dense, Activation, Conv2D, MaxPool2D, BatchNormalization, Dropout, MaxPooling2D\n",
        "import skimage\n",
        "from skimage.transform import rescale, resize\n",
        "\n",
        "import pydot"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Using TensorFlow backend.\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1fZczU8lGkX-",
        "colab_type": "code",
        "outputId": "67786da6-6cfd-40a3-d177-b735376866b8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 122
        }
      },
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly\n",
            "\n",
            "Enter your authorization code:\n",
            "··········\n",
            "Mounted at /content/drive\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "nUcd6yIGduUW",
        "outputId": "64214849-6134-448a-88f2-f4db9b497a92",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        }
      },
      "source": [
        "print(tf.__version__)\n",
        "print(keras.__version__)"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "1.15.0\n",
            "2.2.5\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "v60q28mDHnN9",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "EPOCHS = 100\n",
        "BS = 64\n",
        "DROPOUT_RATE = 0.5\n",
        "FROZEN_LAYER_NUM = 199\n",
        "\n",
        "ADAM_LEARNING_RATE = 0.001\n",
        "SGD_LEARNING_RATE = 0.01\n",
        "SGD_DECAY = 0.0001\n",
        "\n",
        "Resize_pixelsize = 197"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "itKZtFV0F7b1",
        "colab_type": "code",
        "outputId": "04ff3b2c-0da3-470b-f21b-4bcaa87a47a4",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 632
        }
      },
      "source": [
        "vgg_notop = VGGFace(model='senet50', include_top=False, input_shape=(Resize_pixelsize, Resize_pixelsize, 3), pooling='avg')\n",
        "last_layer = vgg_notop.get_layer('avg_pool').output\n",
        "x = Flatten(name='flatten')(last_layer)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "x = Dense(4096, activation='relu', name='fc6')(x)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "x = Dense(1024, activation='relu', name='fc7')(x)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "# l=0\n",
        "# for layer in vgg_notop.layers:\n",
        "#     print(layer,\"[\"+str(l)+\"]\")\n",
        "#     l=l+1\n",
        "\n",
        "batch_norm_indices = [2, 6, 9, 12, 21, 25, 28, 31, 42, 45, 48, 59, 62, 65, 74, 78, 81, 84, 95, 98, 101, 112, 115, 118, 129, 132, 135, 144, 148, 151, 154, 165, 168, 171, 182, 185, 188, 199, 202, 205, 216, 219, 222, 233, 236, 239, 248, 252, 255, 258, 269, 272, 275]    \n",
        "for i in range(FROZEN_LAYER_NUM):\n",
        "    if i not in batch_norm_indices:\n",
        "        vgg_notop.layers[i].trainable = False\n",
        "# print('vgg layer 2 is trainable: ' + str(vgg_notop.layers[2].trainable))\n",
        "# print('vgg layer 3 is trainable: ' + str(vgg_notop.layers[3].trainable))\n",
        "\n",
        "out = Dense(7, activation='softmax', name='classifier')(x)\n",
        "\n",
        "model = Model(vgg_vgg_notop = VGGFace(model='senet50', include_top=False, input_shape=(Resize_pixelsize, Resize_pixelsize, 3), pooling='avg')\n",
        "last_layer = vgg_notop.get_layer('avg_pool').output\n",
        "x = Flatten(name='flatten')(last_layer)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "x = BatchNormalization()(x)\n",
        "x = Dense(4096, activation='relu', name='fc6')(x)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "x = Dense(1024, activation='relu', name='fc7')(x)\n",
        "x = Dropout(DROPOUT_RATE)(x)\n",
        "# l=0\n",
        "# for layer in vgg_notop.layers:\n",
        "#     print(layer,\"[\"+str(l)+\"]\")\n",
        "#     l=l+1\n",
        "\n",
        "batch_norm_indices = [2, 6, 9, 12, 21, 25, 28, 31, 42, 45, 48, 59, 62, 65, 74, 78, 81, 84, 95, 98, 101, 112, 115, 118, 129, 132, 135, 144, 148, 151, 154, 165, 168, 171, 182, 185, 188, 199, 202, 205, 216, 219, 222, 233, 236, 239, 248, 252, 255, 258, 269, 272, 275]    \n",
        "for i in range(FROZEN_LAYER_NUM):\n",
        "    if i not in batch_norm_indices:\n",
        "        vgg_notop.layers[i].trainable = False\n",
        "# print('vgg layer 2 is trainable: ' + str(vgg_notop.layers[2].trainable))\n",
        "# print('vgg layer 3 is trainable: ' + str(vgg_notop.layers[3].trainable))\n",
        "\n",
        "out = Dense(7, activation='softmax', name='classifier')(x)\n",
        "\n",
        "model = Model(vgg_notop.input, out)\n",
        "\n",
        "\n",
        "optim = keras.optimizers.Adam(lr=ADAM_LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)\n",
        "#optim = keras.optimizers.Adam(lr=0.0005, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)\n",
        "sgd = keras.optimizers.SGD(lr=SGD_LEARNING_RATE, momentum=0.9, decay=SGD_DECAY, nesterov=True)\n",
        "\n",
        "# checkpoint\n",
        "cp_filepath='/content/drive/My Drive/cs230 project/models/final/SENET50/weights.best.hdf5'\n",
        "rlrop = keras.callbacks.ReduceLROnPlateau(monitor='val_acc',mode='max',factor=0.5, patience=10, min_lr=0.00001, verbose=1)\n",
        "checkpoint = ModelCheckpoint(cp_filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')\n",
        "callbacks_list = [rlrop,checkpoint]\n",
        "\n",
        "model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])\n",
        "# plot_model(model, to_file='model2.png', show_shapes=True)notop.input, out)\n",
        "\n",
        "\n",
        "optim = keras.optimizers.Adam(lr=ADAM_LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)\n",
        "#optim = keras.optimizers.Adam(lr=0.0005, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)\n",
        "sgd = keras.optimizers.SGD(lr=SGD_LEARNING_RATE, momentum=0.9, decay=SGD_DECAY, nesterov=True)\n",
        "rlrop = keras.callbacks.ReduceLROnPlateau(monitor='val_acc',mode='max',factor=0.5, patience=10, min_lr=0.00001, verbose=1)\n",
        "\n",
        "model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])\n",
        "# plot_model(model, to_file='model2.png', show_shapes=True)"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:66: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:541: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4432: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:190: The name tf.get_default_session is deprecated. Please use tf.compat.v1.get_default_session instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:197: The name tf.ConfigProto is deprecated. Please use tf.compat.v1.ConfigProto instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:203: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:207: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:216: The name tf.is_variable_initialized is deprecated. Please use tf.compat.v1.is_variable_initialized instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:223: The name tf.variables_initializer is deprecated. Please use tf.compat.v1.variables_initializer instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:2041: The name tf.nn.fused_batch_norm is deprecated. Please use tf.compat.v1.nn.fused_batch_norm instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:148: The name tf.placeholder_with_default is deprecated. Please use tf.compat.v1.placeholder_with_default instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4267: The name tf.nn.max_pool is deprecated. Please use tf.nn.max_pool2d instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4271: The name tf.nn.avg_pool is deprecated. Please use tf.nn.avg_pool2d instead.\n",
            "\n",
            "Downloading data from https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_notop_senet50.h5\n",
            "104947712/104944616 [==============================] - 2s 0us/step\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3733: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/optimizers.py:793: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3576: The name tf.log is deprecated. Please use tf.math.log instead.\n",
            "\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "v0mXUNZB-yI5",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "! rm -rf train; mkdir train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/emotion.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/facesdb.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/fer2013/train.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/googlesearch.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/googleset.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/jaffe.zip' -d train\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/umea.zip' -d train"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TUuN9SLX_Qvl",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "! rm -rf dev; mkdir dev\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/fer2013/test-public.zip' -d dev\n",
        "! rm -rf test; mkdir test\n",
        "! unzip -q '/content/drive/My Drive/cs230 project/dataset/fer2013/test-private.zip' -d test"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "egSWDlktpwwQ",
        "colab_type": "code",
        "outputId": "a14db900-1ebe-492c-f122-894505e15bab",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 136
        }
      },
      "source": [
        "%%bash\n",
        "root='/content/test/'\n",
        "IFS=$(echo -en \"\\n\\b\")\n",
        "(for dir in $(ls -1 \"$root\")\n",
        "    do printf \"$dir: \" && ls -i \"$root$dir\" | wc -l\n",
        " done)"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0 angry: 491\n",
            "1 disgust: 55\n",
            "2 fear: 528\n",
            "3 happy: 879\n",
            "4 sad: 594\n",
            "5 surprise: 416\n",
            "6 neutral: 626\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "560jefnZ_Cyq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "\n",
        "def get_datagen(dataset, aug=False):\n",
        "    if aug:\n",
        "        datagen = ImageDataGenerator(\n",
        "                            rescale=1./255,\n",
        "                            featurewise_center=False,\n",
        "                            featurewise_std_normalization=False,\n",
        "                            rotation_range=10,\n",
        "                            width_shift_range=0.1,\n",
        "                            height_shift_range=0.1,\n",
        "                            zoom_range=0.1,\n",
        "                            horizontal_flip=True)\n",
        "    else:\n",
        "        datagen = ImageDataGenerator(rescale=1./255)\n",
        "\n",
        "    return datagen.flow_from_directory(\n",
        "            dataset,\n",
        "            target_size=(197, 197),\n",
        "            color_mode='rgb',\n",
        "            shuffle = True,\n",
        "            class_mode='categorical',\n",
        "            batch_size=BS)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4aQAGQP5_Gpl",
        "colab_type": "code",
        "outputId": "7cb53dfb-49ab-4fa6-b198-6b9b7d944cf8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 102
        }
      },
      "source": [
        "train_generator  = get_datagen('/content/train', True)\n",
        "dev_generator    = get_datagen('/content/dev')\n",
        "test_generator  = get_datagen('/content/test')\n"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/keras_preprocessing/image/utils.py:173: UserWarning: Using \".tiff\" files with multiple bands will cause distortion. Please verify your output.\n",
            "  warnings.warn('Using \".tiff\" files with multiple bands '\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Found 30452 images belonging to 7 classes.\n",
            "Found 3589 images belonging to 7 classes.\n",
            "Found 3589 images belonging to 7 classes.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4sFeoh3eGX_R",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from sklearn.utils import class_weight\n",
        "file_stream = file_io.FileIO('/content/drive/My Drive/cs230 project/collab/fer2013/dev.csv', mode='r')\n",
        "data = pd.read_csv(file_stream)\n",
        "\n",
        "#data = pd.read_csv('fer2013/fer2013.csv')\n",
        "data[' pixels'] = data[' pixels'].apply(lambda x: [int(pixel) for pixel in x.split()])\n",
        "\n",
        "# Retrieve train input and target\n",
        "X, Y = data[' pixels'].tolist(), data['emotion'].values\n",
        "\n",
        "\n",
        "class_weights = class_weight.compute_class_weight('balanced',\n",
        "                                                    np.unique(Y),\n",
        "                                                    Y)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "pLISdlaStbUn",
        "outputId": "8b0dd587-4538-4365-e70f-1d589479af57",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        }
      },
      "source": [
        "history = model.fit_generator(\n",
        "    generator = train_generator,\n",
        "    validation_data=dev_generator, \n",
        "    #steps_per_epoch=28709// BS,\n",
        "    #validation_steps=3509 // BS,\n",
        "    shuffle=True,\n",
        "    epochs=100,\n",
        "    callbacks=callbacks_list,\n",
        "    #callbacks=[rlrop],\n",
        "    use_multiprocessing=True,\n",
        "    class_weight=class_weights\n",
        ") "
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From /tensorflow-1.15.0/python3.6/tensorflow_core/python/ops/math_grad.py:1424: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use tf.where in 2.0, which has the same broadcast rule as np.where\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:1033: The name tf.assign_add is deprecated. Please use tf.compat.v1.assign_add instead.\n",
            "\n",
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:1020: The name tf.assign is deprecated. Please use tf.compat.v1.assign instead.\n",
            "\n",
            "Epoch 1/100\n",
            "238/238 [==============================] - 304s 1s/step - loss: 1.9286 - acc: 0.2698 - val_loss: 1.8309 - val_acc: 0.3062\n",
            "Epoch 2/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 1.5619 - acc: 0.3853 - val_loss: 1.7079 - val_acc: 0.3670\n",
            "Epoch 3/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 1.2920 - acc: 0.5045 - val_loss: 1.2253 - val_acc: 0.5425\n",
            "Epoch 4/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 1.0966 - acc: 0.5979 - val_loss: 1.0938 - val_acc: 0.6138\n",
            "Epoch 5/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 1.0018 - acc: 0.6344 - val_loss: 1.0025 - val_acc: 0.6225\n",
            "Epoch 6/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.9410 - acc: 0.6540 - val_loss: 1.0018 - val_acc: 0.6367\n",
            "Epoch 7/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.8925 - acc: 0.6747 - val_loss: 1.0524 - val_acc: 0.6289\n",
            "Epoch 8/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.8576 - acc: 0.6869 - val_loss: 0.9567 - val_acc: 0.6626\n",
            "Epoch 9/100\n",
            "238/238 [==============================] - 289s 1s/step - loss: 0.8220 - acc: 0.7035 - val_loss: 1.0365 - val_acc: 0.6397\n",
            "Epoch 10/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.7972 - acc: 0.7099 - val_loss: 0.9300 - val_acc: 0.6601\n",
            "Epoch 11/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.7684 - acc: 0.7218 - val_loss: 0.9203 - val_acc: 0.6640\n",
            "Epoch 12/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.7374 - acc: 0.7339 - val_loss: 0.8976 - val_acc: 0.6799\n",
            "Epoch 13/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.7203 - acc: 0.7388 - val_loss: 0.9236 - val_acc: 0.6637\n",
            "Epoch 14/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.6913 - acc: 0.7511 - val_loss: 0.9009 - val_acc: 0.6863\n",
            "Epoch 15/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.6752 - acc: 0.7586 - val_loss: 0.9153 - val_acc: 0.6826\n",
            "Epoch 16/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.6508 - acc: 0.7665 - val_loss: 0.9233 - val_acc: 0.6645\n",
            "Epoch 17/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.6285 - acc: 0.7754 - val_loss: 0.9636 - val_acc: 0.6799\n",
            "Epoch 18/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.6061 - acc: 0.7812 - val_loss: 0.9318 - val_acc: 0.6888\n",
            "Epoch 19/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.5843 - acc: 0.7904 - val_loss: 0.9421 - val_acc: 0.6874\n",
            "Epoch 20/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.5682 - acc: 0.7966 - val_loss: 0.9347 - val_acc: 0.6885\n",
            "Epoch 21/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.5411 - acc: 0.8054 - val_loss: 1.0244 - val_acc: 0.6651\n",
            "Epoch 22/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.5347 - acc: 0.8118 - val_loss: 0.9597 - val_acc: 0.6838\n",
            "Epoch 23/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.5034 - acc: 0.8196 - val_loss: 0.9656 - val_acc: 0.6857\n",
            "Epoch 24/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.4907 - acc: 0.8270 - val_loss: 0.9795 - val_acc: 0.6776\n",
            "Epoch 25/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.4718 - acc: 0.8317 - val_loss: 1.0614 - val_acc: 0.6640\n",
            "Epoch 26/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.4516 - acc: 0.8386 - val_loss: 1.1931 - val_acc: 0.6570\n",
            "Epoch 27/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.4353 - acc: 0.8446 - val_loss: 0.9835 - val_acc: 0.6935\n",
            "Epoch 28/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.4200 - acc: 0.8502 - val_loss: 1.0621 - val_acc: 0.6907\n",
            "Epoch 29/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.4071 - acc: 0.8572 - val_loss: 1.0959 - val_acc: 0.6812\n",
            "Epoch 30/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.3896 - acc: 0.8623 - val_loss: 1.0924 - val_acc: 0.6932\n",
            "Epoch 31/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.3767 - acc: 0.8665 - val_loss: 1.2562 - val_acc: 0.6612\n",
            "Epoch 32/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.3601 - acc: 0.8740 - val_loss: 1.0748 - val_acc: 0.6890\n",
            "Epoch 33/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.3534 - acc: 0.8744 - val_loss: 1.1720 - val_acc: 0.6832\n",
            "Epoch 34/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.3327 - acc: 0.8833 - val_loss: 1.2600 - val_acc: 0.6734\n",
            "Epoch 35/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.3240 - acc: 0.8849 - val_loss: 1.1130 - val_acc: 0.6851\n",
            "Epoch 36/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.3064 - acc: 0.8916 - val_loss: 1.1135 - val_acc: 0.6829\n",
            "Epoch 37/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.2918 - acc: 0.8976 - val_loss: 1.1713 - val_acc: 0.6776\n",
            "\n",
            "Epoch 00037: ReduceLROnPlateau reducing learning rate to 0.004999999888241291.\n",
            "Epoch 38/100\n",
            "238/238 [==============================] - 290s 1s/step - loss: 0.2315 - acc: 0.9185 - val_loss: 1.2643 - val_acc: 0.7130\n",
            "Epoch 39/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.2158 - acc: 0.9239 - val_loss: 1.2481 - val_acc: 0.7088\n",
            "Epoch 40/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.2042 - acc: 0.9305 - val_loss: 1.3244 - val_acc: 0.6927\n",
            "Epoch 41/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.1900 - acc: 0.9344 - val_loss: 1.3064 - val_acc: 0.7060\n",
            "Epoch 42/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.1853 - acc: 0.9366 - val_loss: 1.3902 - val_acc: 0.6943\n",
            "Epoch 43/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.1793 - acc: 0.9382 - val_loss: 1.3389 - val_acc: 0.7086\n",
            "Epoch 44/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.1682 - acc: 0.9421 - val_loss: 1.3948 - val_acc: 0.7063\n",
            "Epoch 45/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.1677 - acc: 0.9411 - val_loss: 1.4519 - val_acc: 0.6957\n",
            "Epoch 46/100\n",
            "238/238 [==============================] - 294s 1s/step - loss: 0.1614 - acc: 0.9444 - val_loss: 1.3742 - val_acc: 0.6982\n",
            "Epoch 47/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.1557 - acc: 0.9475 - val_loss: 1.4159 - val_acc: 0.7038\n",
            "Epoch 48/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.1517 - acc: 0.9480 - val_loss: 1.4185 - val_acc: 0.7097\n",
            "\n",
            "Epoch 00048: ReduceLROnPlateau reducing learning rate to 0.0024999999441206455.\n",
            "Epoch 49/100\n",
            "238/238 [==============================] - 294s 1s/step - loss: 0.1274 - acc: 0.9569 - val_loss: 1.4387 - val_acc: 0.7060\n",
            "Epoch 50/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.1115 - acc: 0.9598 - val_loss: 1.4947 - val_acc: 0.7122\n",
            "Epoch 51/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.1096 - acc: 0.9624 - val_loss: 1.5335 - val_acc: 0.7099\n",
            "Epoch 52/100\n",
            "238/238 [==============================] - 294s 1s/step - loss: 0.1083 - acc: 0.9618 - val_loss: 1.5424 - val_acc: 0.7125\n",
            "Epoch 53/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.1025 - acc: 0.9647 - val_loss: 1.5267 - val_acc: 0.7069\n",
            "Epoch 54/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.1002 - acc: 0.9650 - val_loss: 1.5535 - val_acc: 0.7122\n",
            "Epoch 55/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0946 - acc: 0.9678 - val_loss: 1.5999 - val_acc: 0.7136\n",
            "Epoch 56/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0994 - acc: 0.9666 - val_loss: 1.4954 - val_acc: 0.7083\n",
            "Epoch 57/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0944 - acc: 0.9674 - val_loss: 1.5839 - val_acc: 0.7108\n",
            "Epoch 58/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0921 - acc: 0.9691 - val_loss: 1.6673 - val_acc: 0.7127\n",
            "Epoch 59/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0892 - acc: 0.9695 - val_loss: 1.6237 - val_acc: 0.7105\n",
            "Epoch 60/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0876 - acc: 0.9702 - val_loss: 1.6213 - val_acc: 0.7108\n",
            "Epoch 61/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0861 - acc: 0.9704 - val_loss: 1.6579 - val_acc: 0.7122\n",
            "Epoch 62/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0849 - acc: 0.9712 - val_loss: 1.5693 - val_acc: 0.7099\n",
            "Epoch 63/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0819 - acc: 0.9714 - val_loss: 1.6248 - val_acc: 0.7116\n",
            "Epoch 64/100\n",
            "238/238 [==============================] - 291s 1s/step - loss: 0.0848 - acc: 0.9709 - val_loss: 1.7080 - val_acc: 0.7122\n",
            "Epoch 65/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0825 - acc: 0.9712 - val_loss: 1.6478 - val_acc: 0.7136\n",
            "\n",
            "Epoch 00065: ReduceLROnPlateau reducing learning rate to 0.0012499999720603228.\n",
            "Epoch 66/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0742 - acc: 0.9739 - val_loss: 1.6337 - val_acc: 0.7141\n",
            "Epoch 67/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0664 - acc: 0.9769 - val_loss: 1.6322 - val_acc: 0.7133\n",
            "Epoch 68/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0671 - acc: 0.9755 - val_loss: 1.7225 - val_acc: 0.7197\n",
            "Epoch 69/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0623 - acc: 0.9777 - val_loss: 1.7324 - val_acc: 0.7152\n",
            "Epoch 70/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0677 - acc: 0.9764 - val_loss: 1.7170 - val_acc: 0.7169\n",
            "Epoch 71/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0628 - acc: 0.9771 - val_loss: 1.7341 - val_acc: 0.7169\n",
            "Epoch 72/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0613 - acc: 0.9774 - val_loss: 1.7655 - val_acc: 0.7158\n",
            "Epoch 73/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0655 - acc: 0.9760 - val_loss: 1.7788 - val_acc: 0.7180\n",
            "Epoch 74/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0577 - acc: 0.9798 - val_loss: 1.7498 - val_acc: 0.7158\n",
            "Epoch 75/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0618 - acc: 0.9788 - val_loss: 1.7415 - val_acc: 0.7205\n",
            "Epoch 76/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0593 - acc: 0.9779 - val_loss: 1.7481 - val_acc: 0.7186\n",
            "Epoch 77/100\n",
            "238/238 [==============================] - 292s 1s/step - loss: 0.0566 - acc: 0.9813 - val_loss: 1.7929 - val_acc: 0.7133\n",
            "Epoch 78/100\n",
            "238/238 [==============================] - 298s 1s/step - loss: 0.0624 - acc: 0.9783 - val_loss: 1.7912 - val_acc: 0.7138\n",
            "Epoch 79/100\n",
            "Epoch 78/100\n",
            "238/238 [==============================] - 298s 1s/step - loss: 0.0610 - acc: 0.9783 - val_loss: 1.7777 - val_acc: 0.7169\n",
            "Epoch 80/100\n",
            "238/238 [==============================] - 298s 1s/step - loss: 0.0587 - acc: 0.9793 - val_loss: 1.7775 - val_acc: 0.7166\n",
            "Epoch 81/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0540 - acc: 0.9808 - val_loss: 1.8083 - val_acc: 0.7141\n",
            "Epoch 82/100\n",
            "238/238 [==============================] - 299s 1s/step - loss: 0.0578 - acc: 0.9793 - val_loss: 1.7897 - val_acc: 0.7133\n",
            "Epoch 83/100\n",
            "238/238 [==============================] - 298s 1s/step - loss: 0.0540 - acc: 0.9814 - val_loss: 1.8114 - val_acc: 0.7105\n",
            "Epoch 84/100\n",
            "238/238 [==============================] - 298s 1s/step - loss: 0.0589 - acc: 0.9799 - val_loss: 1.7968 - val_acc: 0.7125\n",
            "Epoch 85/100\n",
            "238/238 [==============================] - 299s 1s/step - loss: 0.0549 - acc: 0.9804 - val_loss: 1.8346 - val_acc: 0.7138\n",
            "\n",
            "Epoch 00085: ReduceLROnPlateau reducing learning rate to 0.0006249999860301614.\n",
            "Epoch 86/100\n",
            "238/238 [==============================] - 299s 1s/step - loss: 0.0529 - acc: 0.9809 - val_loss: 1.8162 - val_acc: 0.7197\n",
            "Epoch 87/100\n",
            "238/238 [==============================] - 296s 1s/step - loss: 0.0543 - acc: 0.9810 - val_loss: 1.7974 - val_acc: 0.7164\n",
            "Epoch 88/100\n",
            "238/238 [==============================] - 293s 1s/step - loss: 0.0497 - acc: 0.9826 - val_loss: 1.8164 - val_acc: 0.7122\n",
            "Epoch 89/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0481 - acc: 0.9832 - val_loss: 1.8189 - val_acc: 0.7122\n",
            "Epoch 90/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0507 - acc: 0.9824 - val_loss: 1.8363 - val_acc: 0.7150\n",
            "Epoch 91/100\n",
            "\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0464 - acc: 0.9830 - val_loss: 1.8458 - val_acc: 0.7133\n",
            "Epoch 92/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0491 - acc: 0.9820 - val_loss: 1.8683 - val_acc: 0.7180\n",
            "Epoch 93/100\n",
            "238/238 [==============================] - 295s 1s/step - loss: 0.0491 - acc: 0.9826 - val_loss: 1.8522 - val_acc: 0.7158\n",
            "Epoch 94/100\n",
            "238/238 [==============================] - 294s 1s/step - loss: 0.0460 - acc: 0.9836 - val_loss: 1.8493 - val_acc: 0.7200\n",
            "Epoch 95/100\n",
            "238/238 [==============================] - 295s 1s/step - loss: 0.0478 - acc: 0.9836 - val_loss: 1.8648 - val_acc: 0.7164\n",
            "\n",
            "Epoch 00095: ReduceLROnPlateau reducing learning rate to 0.0003124999930150807.\n",
            "Epoch 96/100\n",
            "238/238 [==============================] - 296s 1s/step - loss: 0.0476 - acc: 0.9833 - val_loss: 1.8551 - val_acc: 0.7166\n",
            "Epoch 97/100\n",
            "238/238 [==============================] - 296s 1s/step - loss: 0.0472 - acc: 0.9825 - val_loss: 1.8611 - val_acc: 0.7166\n",
            "Epoch 98/100\n",
            "238/238 [==============================] - 294s 1s/step - loss: 0.0470 - acc: 0.9833 - val_loss: 1.8692 - val_acc: 0.7147\n",
            "Epoch 99/100\n",
            "238/238 [==============================] - 295s 1s/step - loss: 0.0443 - acc: 0.9843 - val_loss: 1.8743 - val_acc: 0.7158\n",
            "Epoch 100/100\n",
            "238/238 [==============================] - 297s 1s/step - loss: 0.0467 - acc: 0.9832 - val_loss: 1.8815 - val_acc: 0.7133\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JSSv08SHF0bC",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 68
        },
        "outputId": "4a627349-854b-4df6-9009-331ca7bbc604"
      },
      "source": [
        "print('\\n# Evaluate on dev data')\n",
        "results_dev = model.evaluate_generator(dev_generator, 3509 // BS)\n",
        "print('dev loss, dev acc:', results_dev)"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\n",
            "# Evaluate on dev data\n",
            "dev loss, dev acc: [1.8830583846127544, 0.7135416666666666]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ev4sDYDlOsqk",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 68
        },
        "outputId": "fad7c216-c266-4f76-ce47-fd8c2d194d96"
      },
      "source": [
        "print('\\n# Evaluate on test data')\n",
        "results_test = model.evaluate_generator(test_generator, 3509 // BS)\n",
        "print('test loss, test acc:', results_test)"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\n",
            "# Evaluate on test data\n",
            "test loss, test acc: [1.8335271411471896, 0.7155671296296297]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "m9f7smhHUQus",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 590
        },
        "outputId": "aaab3605-a12b-4fb8-834a-9993a91402f4"
      },
      "source": [
        "# list all data in history\n",
        "print(history.history.keys())\n",
        "# summarize history for accuracy\n",
        "plt.plot(history.history['acc'])\n",
        "plt.plot(history.history['val_acc'])\n",
        "plt.title('model accuracy')\n",
        "plt.ylabel('accuracy')\n",
        "plt.xlabel('epoch')\n",
        "plt.legend(['train', 'dev'], loc='upper left')\n",
        "plt.show()\n",
        "# summarize history for loss\n",
        "plt.plot(history.history['loss'])\n",
        "plt.plot(history.history['val_loss'])\n",
        "plt.title('model loss')\n",
        "plt.ylabel('loss')\n",
        "plt.xlabel('epoch')\n",
        "plt.legend(['train', 'dev'], loc='upper left')\n",
        "plt.show()"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "dict_keys(['val_loss', 'val_acc', 'loss', 'acc', 'lr'])\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nA7xDD4nGl4YsAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "F-QKHTmJQhi1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "epoch_str = '-EPOCHS_' + str(EPOCHS)\n",
        "test_acc = 'test_acc_%.3f' % results_test[1]\n",
        "model.save('/content/drive/My Drive/cs230 project/models/final/' + 'SENET50-WCW-' + epoch_str + test_acc + '.h5')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yJceV2fuFEfQ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}